package service

import (
	"errors"
	"fmt"
	"im/internal/model"
	"im/pkg/databases"
	"im/pkg/logger"
	"time"

	"gorm.io/gorm"
)

// ApplyToAddFriend 申请添加好友
func ApplyToAddFriend(ownerUserId, friendUserId int, ReqMsg string) error {
	if ownerUserId == friendUserId {
		return errors.New("不能对自己进行该操作")
	}
	friend := model.User{
		Id: friendUserId,
	}
	result := databases.GetGorm().Take(&friend)
	if errors.Is(result.Error, gorm.ErrRecordNotFound) {
		return errors.New("用户不存在")
	} else if result.Error != nil {
		logger.Error(fmt.Sprintf("数据库查询错误: %s", result.Error.Error()))
		return result.Error
	} else if friend.Status != "normal" {
		return errors.New("用户状态异常")
	}
	inBlock, err := IsBlock(friendUserId, ownerUserId)
	if err != nil {
		return err
	} else if inBlock {
		return errors.New("对方拒绝你添加他为好友")
	}
	inBlock, err = IsBlock(ownerUserId, friendUserId)
	if err != nil {
		return err
	} else if inBlock {
		return errors.New("请勿添加黑名单中的用户为好友")
	}
	isFriend, err := IsBothFriend(ownerUserId, friendUserId)
	if err != nil {
		return err
	} else if isFriend {
		return errors.New("对方已经是你的好友了，请勿重复添加")
	}
	//判断是否有申请还在审核中
	hasRequest := model.ImUserRequest{}
	result = databases.GetGorm().Where("handle_result = ?", 0).Where(&model.ImUserRequest{
		FromUserId: ownerUserId,
		ToUserId:   friendUserId,
	}).Take(&hasRequest)
	if errors.Is(result.Error, gorm.ErrRecordNotFound) {
		//	不做处理
	} else if result.Error != nil {
		logger.Error(fmt.Sprintf("数据库查询错误: %s", result.Error.Error()))
		return result.Error
	} else if result.RowsAffected > 0 {
		return errors.New("好友已发送")
	}
	//申请添加好友
	request := model.ImUserRequest{
		FromUserId: ownerUserId,
		ToUserId:   friendUserId,
		ReqMsg:     ReqMsg,
	}
	result = databases.GetGorm().Create(&request)
	if result.Error != nil {
		logger.Error(fmt.Sprintf("数据库新增错误: %s", result.Error.Error()))
		return result.Error
	}
	return nil
}

// RespondFriendApply 回应好友申请
func RespondFriendApply(ownerUserId, applyId int, handleResult int8) (bool, error) {
	apply := model.ImUserRequest{}
	result := databases.GetGorm().Take(&apply, applyId)
	if result.Error != nil {
		return false, result.Error
	}
	if apply.ToUserId != ownerUserId {
		return false, errors.New("非法操作")
	}
	if apply.HandleResult != 0 {
		return false, errors.New("请勿重复操作")
	}

	apply.HandleResult = handleResult
	apply.HandleTime = time.Now().Unix()
	if handleResult == -1 {
		databases.GetGorm().Save(&apply)
		return false, nil
	}
	err := databases.GetGorm().Transaction(func(tx *gorm.DB) error {
		//更新请求状态
		if err := tx.Save(&apply).Error; err != nil {
			return err
		}
		ok, err := IsFriend(apply.ToUserId, apply.FromUserId)
		if err != nil {
			return err
		}
		if !ok {
			relation1 := model.ImUserRelation{
				OwnerUserId:  apply.ToUserId,
				FriendUserId: apply.FromUserId,
				LatestNews:   "我通过了你的朋友验证请求，现在我们可以开始聊天了",
			}
			if err = tx.Create(&relation1).Error; err != nil {
				return err
			}
		}
		ok, err = IsFriend(apply.FromUserId, apply.ToUserId)
		if !ok {
			relation1 := model.ImUserRelation{
				OwnerUserId:  apply.FromUserId,
				FriendUserId: apply.ToUserId,
				UnreadCount:  1,
			}
			if err = tx.Create(&relation1).Error; err != nil {
				return err
			}
		}
		return nil
	})
	if err != nil {
		return false, err
	}
	return true, nil
}

// DeleteFriend 删除好友关系
func DeleteFriend(ownerUserId, friendUserId int) error {
	if ownerUserId == friendUserId {
		return errors.New("不能对自己进行该操作")
	}
	ok, err := IsFriend(ownerUserId, friendUserId)
	if err != nil {
		return err
	}
	if !ok {
		return errors.New("他不是你的好友")
	}
	friend := model.ImUserRelation{}
	result := databases.GetGorm().Where(&model.ImUserRelation{
		OwnerUserId:  ownerUserId,
		FriendUserId: friendUserId,
	}).Take(&friend)
	if result.Error != nil {
		return result.Error
	}
	result = databases.GetGorm().Delete(&friend)
	if result.Error != nil {
		return result.Error
	}
	return nil
}

// SetFriendRemark 设置好友备注
func SetFriendRemark(ownerUserId, friendUserId int, remark string) (bool, error) {
	if ownerUserId == friendUserId {
		return false, errors.New("不能对自己进行该操作")
	}
	friend := model.ImUserRelation{}
	result := databases.GetGorm().Where(&model.ImUserRelation{
		OwnerUserId:  ownerUserId,
		FriendUserId: friendUserId,
	}).Take(&friend)
	if result.Error != nil {
		logger.Error(fmt.Sprintf("数据库查询错误: %s", result.Error.Error()))
		return false, result.Error
	}
	if friend.Remark == remark {
		return false, errors.New("备注未修改")
	}
	friend.Remark = remark
	result = databases.GetGorm().Save(&friend)
	if result.Error != nil {
		return false, result.Error
	}
	return true, nil
}

// AddBlock 添加黑名单
func AddBlock(ownerUserId, friendUserId int) error {
	if ownerUserId == friendUserId {
		return errors.New("不能对自己进行该操作")
	}
	if result := databases.GetGorm().Take(&model.User{
		Id: friendUserId,
	}); result.Error != nil {
		return result.Error
	}
	block, err := IsBlock(ownerUserId, friendUserId)
	if err != nil {
		return err
	}
	if block {
		return errors.New("已经在黑名单中")
	}
	result := databases.GetGorm().Create(&model.ImUserBlock{
		OwnerUserId: ownerUserId,
		BlockUserId: friendUserId,
	})
	return result.Error
}

// RemoveBlock 移除黑名单
func RemoveBlock(ownerUserId, friendUserId int) error {
	if ownerUserId == friendUserId {
		return errors.New("不能对自己进行该操作")
	}
	block := model.ImUserBlock{
		OwnerUserId: ownerUserId,
		BlockUserId: friendUserId,
	}
	result := databases.GetGorm().Take(&block)
	if result.Error != nil {
		return result.Error
	}
	return databases.GetGorm().Delete(&block).Error
}

// GetFriendInfo 获取好友信息
func GetFriendInfo(ownerUserId, friendUserId int) (*model.User, error) {
	if ownerUserId == friendUserId {
		return nil, errors.New("不能对自己进行该操作")
	}
	boolean, err := IsBothFriend(ownerUserId, friendUserId)
	if err != nil {
		return nil, err
	}
	if !boolean {
		return nil, errors.New("他不是你的好友")
	}
	user := model.User{Id: friendUserId}
	result := databases.GetGorm().Take(&user)
	if result.Error != nil {
		return nil, result.Error
	}
	return &user, nil
}

// GetDesignatedFriends 批量获取好友信息
func GetDesignatedFriends(ownerUserId int, ids []int) ([]model.ImUserRelation, error) {
	var friends []model.ImUserRelation
	result := databases.GetGorm().Where("owner_user_id = ? AND friend_user_id IN ?", ownerUserId, ids).Find(&friends)
	if result.Error != nil {
		return nil, result.Error
	}
	return friends, nil
}

// IsFriend 判断是否是好友
func IsFriend(ownerUserId, friendUserId int) (bool, error) {
	if ownerUserId == friendUserId {
		return false, errors.New("不能对自己进行该操作")
	}
	friend := model.ImUserRelation{}
	result := databases.GetGorm().Where(&model.ImUserRelation{
		OwnerUserId:  ownerUserId,
		FriendUserId: friendUserId,
	}).Take(&friend)
	if errors.Is(result.Error, gorm.ErrRecordNotFound) {
		return false, nil
	} else if result.Error != nil {
		logger.Error(fmt.Sprintf("数据库查询错误: %s", result.Error.Error()))
		return false, result.Error
	}
	return true, nil
}

// IsBothFriend 检查双向好友关系
func IsBothFriend(ownerUserId, friendUserId int) (bool, error) {
	if ownerUserId == friendUserId {
		return false, errors.New("不能对自己进行该操作")
	}
	isFriend1, err := IsFriend(ownerUserId, friendUserId)
	if err != nil {
		return false, err
	}
	isFriend2, err := IsFriend(friendUserId, ownerUserId)
	if err != nil {
		return false, err
	}

	// 只有双方都互为好友才算双向好友关系
	return isFriend1 && isFriend2, nil
}

// GetFriendIDs 获取好友ID列表
func GetFriendIDs(ownerUserId int) ([]int, error) {
	var ids []int
	result := databases.GetGorm().Model(&model.ImUserRelation{
		OwnerUserId: ownerUserId,
	}).Pluck("friend_user_id", &ids)
	if !errors.Is(result.Error, gorm.ErrRecordNotFound) && result.Error != nil {
		logger.Error(fmt.Sprintf("数据库查询错误: %s", result.Error.Error()))
		return nil, result.Error
	}
	return ids, nil
}

// GetPaginationFriendsApplyTo 获取发送的申请列表
func GetPaginationFriendsApplyTo(userId int, where []int) ([]model.ImUserRequest, error) {
	var requests []model.ImUserRequest
	result := databases.GetGorm().Where("from_user_id = ? AND handle_result IN ?", userId, where).Find(&requests)
	if !errors.Is(result.Error, gorm.ErrRecordNotFound) && result.Error != nil {
		logger.Error(fmt.Sprintf("数据库查询错误: %s", result.Error.Error()))
		return nil, result.Error
	}
	return requests, nil
}

// GetPaginationFriendsApplyFrom 获取接收的申请列表
func GetPaginationFriendsApplyFrom(userId int, where []int) ([]model.ImUserRequest, error) {
	var requests []model.ImUserRequest
	result := databases.GetGorm().Where("to_user_id = ? AND handle_result IN ?", userId, where).Find(&requests)
	if !errors.Is(result.Error, gorm.ErrRecordNotFound) && result.Error != nil {
		logger.Error(fmt.Sprintf("数据库查询错误: %s", result.Error.Error()))
		return nil, result.Error
	}
	return requests, nil
}

// IsBlock 判断是否在黑名单中
func IsBlock(ownerUserId, friendUserId int) (bool, error) {
	if ownerUserId == friendUserId {
		return false, errors.New("不能对自己进行该操作")
	}
	block := model.ImUserBlock{}
	result := databases.GetGorm().Where(&model.ImUserBlock{
		OwnerUserId: ownerUserId,
		BlockUserId: friendUserId,
	}).Take(&block)
	if errors.Is(result.Error, gorm.ErrRecordNotFound) {
		return false, nil
	} else if result.Error != nil {
		logger.Error(fmt.Sprintf("数据库查询错误: %s", result.Error.Error()))
		return false, result.Error
	}
	return true, nil
}
